/*  
     PlAr is Platform Arena: a 2D multiplayer shooting game
     Cop
     * yright (C) 2009 Ragagnin Antonio <spocchio@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package plar.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.collision.*;

public class Element  {

	public ActionManager actions;
	public HashMap<String, Object> properties;
	public Parameters stdinfo;
	public BodyDef bd;
	public PolygonDef pd;
	public Body body;
	public Level level;
	
	public Element() {
		stdinfo = new Parameters();
		actions = new ActionManager();
		properties = new HashMap<String, Object>();
		stdinfo.parameters.put("me", this);
	
		setProperty("type", "block");
		setProperty("initialPosition", new Vec2(0,0));
		
		setProperty("isBullet",false);
		setProperty("isRunnable",false);
		
		setProperty("density",1000f);
		setProperty("friction",2f);
		setProperty("restitution",0.1f);
		setProperty("static",true);
		setProperty("size",new Vec2(0,0));
		setProperty("shape",new ArrayList <Vec2>());
		setProperty("speedLimit", new Vec2(5f,8f));
		setProperty("isStatic", true);
		setProperty("linearDamping", 0f);
		setProperty("isActive", true);
		setProperty("lifeTime", -1); //eternity
		//setProperty("bodyType",Body.e_staticType);
		//setProperty("bodyType",Body.e_dynamicType);
		
		actions.addAction("destroy", new Destroy());
		actions.addAction("lifetimer", new LifeTimer());
		
		setStaticSprite("res/element.png");
		
		initBox();
	    
		
	}	
	public void initBox()
	
	{
		body=null;
		pd=null;
		bd=null;
		pd = new PolygonDef();
		bd = new BodyDef();
		bd.fixedRotation=true;
		}


	
	public ArrayList<Sprite> getCurrentSpriteSet() {
		return (ArrayList<Sprite>) getProperty("currentSpriteSet");
	}
	
	public AABB getAABB()
	{
		AABB r=new AABB();
		Vec2 s=getSize();
		Vec2 p=getPosition();
		r.lowerBound=new Vec2(p.x-s.x/2,p.y-s.y/2);
		r.upperBound=new Vec2(p.x+s.x/2,p.y+s.y/2);
		return r;
	}
	public Vec2 getSize()
	
	{
		Vec2 size = new Vec2(0,0);
		Vec2 min = new Vec2(0,0);
		Vec2 max = new Vec2(0,0);
		
		ArrayList <Vec2> al = (ArrayList <Vec2>)pd.getVertexList();
		String str="n opf ver:"+al.size();
		for(Vec2 v: al)
		{
			str+=" - "+v;
		 
			 if(v.y<min.y || min.y==0) min.y=v.y;
			 if(v.x<min.x || min.x==0) min.x=v.x;
			 if(v.y>max.y || max.y==0) max.y=v.y;
			 if(v.x>max.x || max.x==0) max.x=v.x;
		}
		size.y=max.y-min.y;
		size.x=max.x-min.x;
		
		str+="size:"+size+" cdm: "+body.getWorldCenter();
		//Common.info(str);
		return size;
	}
	
	public void JBoxSincronize()
	{
		
		boolean st = (Boolean)getProperty("isStatic");
		//boolean ik = (Boolean) getProperty("isKinematic");
		boolean ia=(Boolean) getProperty("isActive");
		boolean ib=(Boolean) getProperty("isBullet");
		//float ld=(Float) getProperty("linearDumping");
		//bd.linearDamping=ld;
			
			pd.isSensor=!ia;//ia;
		
		if(st)	body.m_type=Body.e_staticType;
		//else if(ik) body.m_type=Body.e_kynematicType;
		else body.m_type=Body.e_dynamicType;
		if(ib)
		{
			body.setBullet(ib);
//			body.m_type=Body.e_bulletFlag;
		}
		
		pd.restitution=(Float)getProperty("restitution");
		pd.density=(Float)getProperty("density");
		pd.friction=(Float)getProperty("friction");

		List <Vec2> shape = (List <Vec2>)getProperty("shape");
		if(shape!=null && shape.size()>0)
		{
			
			pd.vertices=shape;
		}
		
		
		body.createShape(pd);
		//Common.info(7,""+body.m_flags);
		//body.m_flags+=body.e_fixedRotationFlag;
		
		//Common.info(7,""+body.m_flags);
		if(!st)
		{
				body.setMassFromShapes();
				
		}

	}

	public Vec2 getPosition() {
		return body.getWorldCenter();
	}
	public void setPosition(float x,float y) {
		bd.position=new Vec2(x,y);
	}
	public void setShape(ArrayList <Vec2> s) {
		
		pd.vertices.clear();
		pd.vertices.addAll(s);
	}
	public Vec2 getSpeed()
	{
		return body.m_linearVelocity;
	}
	public Object getProperty(String s) {
		return properties.get(s);
	}

	public void applyForce(Vec2 v) {
		Vec2 before = new Vec2(getSpeed().x,getSpeed().y);
		body.applyForce(v, body.getWorldCenter());
		//Common.info(7,"Element.applyForce(): ["+v+"] "+before+" -> "+getSpeed());
		
	}

	public void applyImpulse(Vec2 v)
	{
		Vec2 before = new Vec2(getSpeed().x,getSpeed().y);
		body.applyImpulse(v, body.getWorldCenter());
	//	Common.info(7,"Element.applyImpulse(): ["+v+"] "+before+" -> "+getSpeed());
	}

	public void applySpeed(Vec2 v)
	{
		
		v.x=body.getMass()*v.x;
		v.y=body.getMass()*v.y;
		applyImpulse(v);
		Vec2 after = new Vec2(getSpeed().x,getSpeed().y);
		//Vec2 delta = new Vec2(after.x-before.x,after.y-before.y);
		
		}

public void setSpeed(Vec2 v)
	{
		Vec2 cv = getSpeed();
		Vec2 dv = getSpeed();
		dv.x=-cv.x+v.x;
		dv.y=-cv.y+v.y;
		if(v.x==0) dv.x=0;
		if(v.y==0) dv.y=0;
		addSpeed(dv);
	}
	public void addSpeed(Vec2 dv){
		Vec2 m=new Vec2(body.getMass()*dv.x,body.getMass()*dv.y);
		applyImpulse(dv);
	}
	public void destroyShapes()
	{
		while (body.getShapeList()!=null) body.destroyShape(body.getShapeList());
	}
		
	public void deEdge()
	{
		lilJump();
	}
	public void lilJump()
	{
		addSpeed(new Vec2(0.1f,0f));
	}
	public void setSize(float x,float y)
	{
		pd.clearVertices();
		pd.setAsBox(x/2,y/2);
	}
	
	public void run() { 
		stdinfo.put("subAction","main");
		
		actions.runAll(stdinfo);
		setProperty("collisionList",null);
	//	deEdge();
	}

	public void setProperty(String s, Object o) {
		if(s=="collisionList")
		{
		 //Common.info("writing on "+this+"."+s+"")
		}
		properties.put(s, o);
	}
	public void setStaticSprite(String str) {
		Sprite s = new Sprite(str, -1);
		s.texturized = true;
		ArrayList<Sprite> ss = new ArrayList<Sprite>();
		ss.add(s);
		setProperty("currentSpriteSet", ss);
	}


}
 
